package com.neusoft.work.service.impl;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.neusoft.work.dao.BedAssignmentDao;
import com.neusoft.work.dao.BedInfoDao;
import com.neusoft.work.dao.CustomerDao;
import com.neusoft.work.dao.HealthManagerCustomerDao;
import com.neusoft.work.dao.OutRegistrationDao;
import com.neusoft.work.dao.UserDao;
import com.neusoft.work.dto.OutRegistrationDto;
import com.neusoft.work.po.BedAssignment;
import com.neusoft.work.po.BedInfo;
import com.neusoft.work.po.Customer;
import com.neusoft.work.po.HealthManagerCustomer;
import com.neusoft.work.po.OutRegistration;
import com.neusoft.work.po.PageResponseBean;
import com.neusoft.work.po.ResponseBean;
import com.neusoft.work.po.User;
import com.neusoft.work.service.OutRegistrationService;


@Service
public class OutRegistrationServiceImpl implements OutRegistrationService {

    @Autowired
    private OutRegistrationDao dao;
    
    @Autowired
    private CustomerDao cd;
    
    @Autowired
    private BedInfoDao bedInfoDao;
    
    @Autowired
    private BedAssignmentDao bad; 
    
	@Autowired
	private HealthManagerCustomerDao healthManagerCustomerDao;
	
    @Autowired
    private UserDao userDao;


    @Override
    public PageResponseBean<List<OutRegistrationDto>> queryAll(String name, Long cur, Long number) {
        // 1. 根据 name 查 customerIds
        List<Integer> customerIds;
        if (name != null && !name.trim().isEmpty()) {
            List<Customer> customers = cd.selectList(
                new QueryWrapper<Customer>()
                    .like("name", name)
                    .select("id")
            );
            if (customers.isEmpty()) {
                // 如果按名字查不到人，直接返回“无数据”
                return new PageResponseBean<>(500, "无数据");
            }
            customerIds = customers.stream()
                                   .map(Customer::getId)
                                   .collect(Collectors.toList());
        } else {
            customerIds = null;
        }

        // 2. 分页查询 OutRegistration，只有 customerIds 非空且非空列表时才加 IN
        Page<OutRegistration> page = new Page<>(cur, number);
        QueryWrapper<OutRegistration> qw = new QueryWrapper<>();
        if (customerIds != null && !customerIds.isEmpty()) {
            qw.in("customerId", customerIds);
        }
        IPage<OutRegistration> result = dao.selectPage(page, qw);

        List<OutRegistration> list = result.getRecords();
        long total = result.getTotal();

        // 3. 如果有数据，才去查客户名和审批人名
        if (total > 0) {
            // 3.1 收集所有要查的 customerId，构造 custMap
            List<Integer> custIds = list.stream()
                .map(OutRegistration::getCustomerId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
            Map<Integer, String> custMap = new HashMap<>();
            if (!custIds.isEmpty()) {
                cd.selectBatchIds(custIds).forEach(c ->
                    custMap.put(c.getId(), c.getName())
                );
            }

            // 3.2 收集所有要查的 operatorUserId，构造 userMap
            List<Integer> opIds = list.stream()
                .map(OutRegistration::getOperatorUserId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
            Map<Integer, String> userMap = new HashMap<>();
            if (!opIds.isEmpty()) {
                userDao.selectBatchIds(opIds).forEach(u ->
                    userMap.put(u.getId(), u.getRealName())
                );
            }

            // 4. 封装 DTO
            List<OutRegistrationDto> dtoList = list.stream().map(entity -> {
                OutRegistrationDto dto = new OutRegistrationDto();
                BeanUtils.copyProperties(entity, dto);
                dto.setCustomerName(custMap.get(entity.getCustomerId()));
                dto.setOperatorUserName(userMap.get(entity.getOperatorUserId()));
                return dto;
            }).collect(Collectors.toList());

            PageResponseBean<List<OutRegistrationDto>> rb = new PageResponseBean<>(dtoList);
            rb.setTotal(total);
            return rb;
        } else {
            // 没有记录
            return new PageResponseBean<>(500, "no data");
        }
    }
	
	@Override
    public ResponseBean<Integer> update(OutRegistration record) {
        // 直接按主键更新，返回影响行数
        int rows = dao.updateById(record);
        if (rows > 0) {
            // 更新成功
            return new ResponseBean<>(rows);
        } else {
            // 更新失败
            return new ResponseBean<>(500, "更新失败，没有找到对应记录");
        }
    }

    @Override
    public ResponseBean<Integer> delete(Integer id) {
        // 按主键删除，返回影响行数
        int rows = dao.deleteById(id);
        if (rows > 0) {
            // 删除成功
            return new ResponseBean<>(rows);
        } else {
            // 删除失败
            return new ResponseBean<>(500, "删除失败，没有找到对应记录");
        }
    }

	@Override
	public ResponseBean<Integer> add(OutRegistration record) {
		// TODO Auto-generated method stub
        // 直接按主键更新，返回影响行数
        int rows = dao.insert(record);
        if (rows > 0) {
            // 更新成功
            return new ResponseBean<>(rows);
        } else {
            // 更新失败
            return new ResponseBean<>(500, "插入失败");
        }
	}

	@Override
	public ResponseBean<Integer> approve(Integer id, Integer approveStatus, Integer operatorUserId) {
	    // 1. 查出外出申请记录，拿到客户ID
	    OutRegistration rec = dao.selectById(id);
	    if (rec == null) {
	        return new ResponseBean<>(500, "申请记录不存在");
	    }

	    // 2. 更新审批状态、审批人、审批时间
	    rec.setApproveStatus(approveStatus);   // 1=通过，2=拒绝
	    rec.setOperatorUserId(operatorUserId);
	    rec.setApproveTime(LocalDateTime.now()
	        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
	    int rows = dao.updateById(rec);

	    // 3. 如果审批通过，就把床位状态改成“外出”
	    if (rows > 0 && approveStatus == 1) {
	        BedAssignment assign = bad.selectOne(new QueryWrapper<BedAssignment>()
	            .eq("customerId", rec.getCustomerId())
	            .eq("isDeleted", false)
	            .last("LIMIT 1"));

	        if (assign != null && assign.getBedNumber() != null) {
	            // 3.2 用 bed_number 更新床位状态为“外出”(3)
	            int updated = bedInfoDao.update(
	                null,
	                new UpdateWrapper<BedInfo>()
	                    .eq("bedNumber", assign.getBedNumber())
	                    .set("status", 3)
	            );
	            // 可选：你可以检查 updated > 0
	        }
	    }

	    return rows > 0
	        ? new ResponseBean<>(rows)
	        : new ResponseBean<>(500, "审批失败");
	}
	
	@Override
	public PageResponseBean<List<OutRegistrationDto>> searchRegistration(
	        Integer healthManagerId, String clientName, Long cur, Long number) {

	    // 1. 获取客户 ID
	    List<HealthManagerCustomer> hmcList = healthManagerCustomerDao.selectList(
	        new QueryWrapper<HealthManagerCustomer>().eq("healthManagerId", healthManagerId)
	    );
	    List<Integer> clientIds = hmcList.stream()
	        .map(HealthManagerCustomer::getCustomerId)
	        .collect(Collectors.toList());

	    // 2. 客户名过滤
	    if (clientName != null && !clientName.trim().isEmpty()) {
	        List<Customer> matched = cd.selectList(
	            new QueryWrapper<Customer>()
	                .like("name", clientName)
	                .select("id")
	        );
	        List<Integer> matchIds = matched.stream()
	            .map(Customer::getId)
	            .collect(Collectors.toList());
	        clientIds.retainAll(matchIds);
	    }

	    if (clientIds.isEmpty()) {
	        return new PageResponseBean<>(500, "无数据");
	    }

	    // 3. 分页查询
	    Page<OutRegistration> page = new Page<>(cur, number);
	    QueryWrapper<OutRegistration> qw = new QueryWrapper<>();
	    qw.in("customerId", clientIds).orderByDesc("outTime");

	    IPage<OutRegistration> result = dao.selectPage(page, qw);
	    List<OutRegistration> list = result.getRecords();
	    long total = result.getTotal();

	    // 4. 客户姓名映射
	    Map<Integer, String> id2CustomerName = cd.selectBatchIds(clientIds)
	        .stream()
	        .collect(Collectors.toMap(Customer::getId, Customer::getName));

	    // 5. 审批人姓名映射（安全处理）
	    Map<Integer, String> id2OperatorName = new HashMap<>();
	    List<Integer> operatorIds = list.stream()
	        .map(OutRegistration::getOperatorUserId)
	        .filter(Objects::nonNull)
	        .distinct()
	        .collect(Collectors.toList());

	    if (!operatorIds.isEmpty()) {
	        List<User> users = userDao.selectBatchIds(operatorIds);
	        id2OperatorName.putAll(users.stream()
	            .collect(Collectors.toMap(User::getId, User::getRealName)));
	    }

	    // 6. 封装 DTO
	    List<OutRegistrationDto> dtoList = list.stream().map(r -> {
	        OutRegistrationDto dto = new OutRegistrationDto();
	        BeanUtils.copyProperties(r, dto);
	        dto.setCustomerName(id2CustomerName.get(r.getCustomerId()));
	        if (r.getOperatorUserId() != null) {
	            dto.setOperatorUserName(id2OperatorName.get(r.getOperatorUserId()));
	        }
	        return dto;
	    }).collect(Collectors.toList());

	    // 7. 返回结果
	    PageResponseBean<List<OutRegistrationDto>> rb = new PageResponseBean<>(dtoList);
	    rb.setTotal(total);
	    return rb;
	}

	    @Override
	    public ResponseBean<Integer> revoke(Integer id) {
	       
	        int rows = dao.deleteById(id);
	        return rows > 0
	            ? new ResponseBean<>(rows)
	            : new ResponseBean<>(500, "撤销失败");
	    }

	    @Override
	    public ResponseBean<Integer> registerReturn(Integer id, String actualReturnTime) {
	        OutRegistration rec = dao.selectById(id);
	        if (rec == null) {
	            return new ResponseBean<>(500, "记录不存在");
	        }
	        rec.setActualReturn(actualReturnTime);
	        int rows = dao.updateById(rec);

	        return rows > 0
	            ? new ResponseBean<>(rows)
	            : new ResponseBean<>(500, "登记失败");
	    }


}
